﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using CodeGame.ServerObjects.ServerWorldEnts;

namespace CodeGame.ServerObjects
{
    class WorldManager
    {
        const int ResourceNodes = 10;

        private Blocks[,] WorldBlocks;

        private List<Entity> Entities = new List<Entity>();
        private List<Entity> NullEntities = new List<Entity>();

        const int SIZE = 80;

        public WorldManager()
        {
            this.WorldBlocks = new Blocks[SIZE, SIZE];
            for (int x = 0; x < SIZE; x++)
            {
                for (int y = 0; y < SIZE; y++)
                {
                    this.WorldBlocks[x, y] = Blocks.Air;
                }
            }

            this.Generate();
        }

        public void Generate()
        {
            Console.WriteLine("Generating World");

            for (int x = 0; x < SIZE; x++)
            {
                for (int y = 0; y < SIZE; y++)
                {
                    if (ServerSingletons.Rand.Next(5) == 0)
                    {
                        this.WorldBlocks[x, y] = Blocks.LongGrass;
                    }
                    else
                    {
                        this.WorldBlocks[x, y] = Blocks.Grass;
                    }
                }
            }

            DedicatedServer.AddTimer(50, new DedicatedServer.TimerRef(this.UpdateResouces));

            for (int i = 0; i < ResourceNodes; i++)
            {
                ResourceNode node = new ResourceNode();
                node.Spawn("SERVER", ServerSingletons.Rand.Next(SIZE * 32), ServerSingletons.Rand.Next(SIZE * 32));
                node.TextureEnt(node.GetPID(), "resourceNode");
                this.NullEntities.Add(node);
                this.AddEntity(node);
            }
        }

        private void UpdateResouces()
        {
            foreach (Entity item in this.Entities)
            {
                item.Update();
            }
        }

        public byte[] GetWorldData()
        {
            byte[] data = new byte[SIZE * SIZE];

            int i = 0;

            for (int x = 0; x < SIZE; x++)
            {
                for (int y = 0; y < SIZE; y++)
                {
                    data[i] = Convert.ToByte((int)this.WorldBlocks[x, y]);
                    i++;
                }
            }

            return data;
        }

        public void AddEntity(Player ply, string id)
        {
            this.Entities.Add(new Entity(id, ply));
        }

        public void AddEntity(Entity ent)
        {
            this.Entities.Add(ent);
        }

        public Entity GetEntity(bool privateID, string id)
        {
            foreach (Entity item in this.Entities)
            {
                if (privateID)
                {
                    if (item.GetPID() == id)
                    {
                        return item;
                    }
                }
                else
                {
                    if (item.GetID() == id)
                    {
                        return item;
                    }
                }
            }
            return null;
        }

        public string Pulse(int radius, int startX, int startY)
        {
            string str = "";

            foreach (Entity item in this.NullEntities)
            {
                Console.WriteLine(this.Distince(startX, startY, item.X, item.Y));
                if (this.Distince(startX, startY, item.X, item.Y) < radius)
                {
                    str += item.X.ToString() + ", " + item.Y.ToString() + " : Private[" + item.GetPID() + "] Public[" + item.GetID() + "]\n";
                }
            }

            return str;
        }

        public double Distince(int x1, int y1, int x2, int y2)
        {
            float num = x1 - x2;
            float num2 = y1 - y2;
            float num3 = num * num + num2 * num2;
            return (float)Math.Sqrt((double)num3);
        }

        public List<Entity> GetAllEntities()
        {
            return this.Entities;
        }
    }
}
